package com.chuangke.sinotrukbudget.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chuangke.core.data.builder.DataBuildConfig;
import com.chuangke.core.data.builder.DataBuilder;
import com.chuangke.core.exception.ChuangkeException;
import com.chuangke.core.page.CkPageQuery;
import com.chuangke.sinotrukbudget.data.builder.BudgetAccountBuilder;
import com.chuangke.sinotrukbudget.model.BudgetControlAccount;
import com.chuangke.sinotrukbudget.model.BudgetControlAccountDept;
import com.chuangke.sinotrukbudget.sdao.BudgetControlAccountDaoService;
import com.chuangke.sinotrukbudget.service.BudgetControlAccountDeptService;
import com.chuangke.sinotrukbudget.service.BudgetControlAccountService;

@Service
public class BudgetControlAccountServiceImpl implements BudgetControlAccountService {

	public static final String CACHE_NAME = "budget_control_account";

	@Autowired
	private BudgetControlAccountDaoService budgetControlAccountDaoService;
	
	@Autowired
	private BudgetControlAccountDeptService budgetControlAccountDeptService ;
	
	@Override
	public void save(BudgetControlAccount record) {
		((BudgetControlAccountService) AopContext.currentProxy()).save(Arrays.asList(record));
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
	public void save(List<BudgetControlAccount> records) {
		if (CollectionUtils.isEmpty(records)) {
			return;
		}
		
		List<BudgetControlAccount> dbRecords = ((BudgetControlAccountService) AopContext.currentProxy()).findList();
		List<String> uniques = dbRecords.stream().map(bca -> bca.getDeptId()+"-"+bca.getControlAccountId()).collect(Collectors.toList()) ;
		records = records.stream().filter(bca -> !uniques.contains(bca.getDeptId()+"-"+bca.getControlAccountId())).collect(Collectors.toList()) ;
		
		budgetControlAccountDaoService.saveOrUpdateBatch(records);
	}

	@CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
	@Override
	public void delete(BudgetControlAccount record) {
		budgetControlAccountDaoService.removeById(record);
	}

	@CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
	@Transactional(rollbackFor = Throwable.class)
	@Override
	public void delete(List<BudgetControlAccount> records) {
		List<String> uniques = records.stream().map(bca -> bca.getDeptId()+"-"+bca.getControlAccountId()).collect(Collectors.toList()) ;
		
		List<BudgetControlAccountDept> dbRecords = budgetControlAccountDeptService.findList();
		dbRecords = dbRecords.stream().filter(bca -> uniques.contains(bca.getDeptId()+"-"+bca.getControlAccountId())).collect(Collectors.toList()) ;
		budgetControlAccountDeptService.delete(dbRecords);
		
		
		List<String> idList = records.stream().map(BudgetControlAccount::getId).collect(Collectors.toList());
		budgetControlAccountDaoService.removeBatchByIds(idList);
	}
	
	@CacheEvict(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
	@Override
	public void deleteByIds(List<String> ids) {
		budgetControlAccountDaoService.removeByIds(ids) ;
	}

	@Cacheable(cacheNames = CACHE_NAME, key = "'" + CACHE_NAME + "'")
	@Override
	public Map<String, BudgetControlAccount> findMap() {
		List<BudgetControlAccount> list = budgetControlAccountDaoService.list();
		return list.stream().collect(Collectors.toMap(BudgetControlAccount::getId, a -> a));
	}

	@Override
	public BudgetControlAccount findById(String id) {
		if (id == null) {
			return null;
		}

		Map<String, BudgetControlAccount> map = ((BudgetControlAccountService) AopContext.currentProxy()).findMap();
		return map.get(id);
	}

	@Override
	public IPage<BudgetControlAccount> page(CkPageQuery page) {
		throw new ChuangkeException("不支持的方法") ;
	}

	@Override
	public List<BudgetControlAccount> findList() {
		Map<String, BudgetControlAccount> map = ((BudgetControlAccountService) AopContext.currentProxy()).findMap();
		
		List<BudgetControlAccount> list = new ArrayList<>(map.values());
		if(!CollectionUtils.isEmpty(list)) {
			DataBuilder.of(list)
			.appendBuilder(new BudgetAccountBuilder(), new DataBuildConfig("controlAccountId", "ccontrolAccountName")).build();
		}
		
		return list ;
	}

	@Override
	public List<BudgetControlAccount> findList(String deptId) {
		List<BudgetControlAccount> allList = ((BudgetControlAccountService) AopContext.currentProxy()).findList();
		if(CollectionUtils.isEmpty(allList)) {
			return new ArrayList<>() ;
		}
		
		Map<String,List<BudgetControlAccount>> groupMap = allList.stream().collect(Collectors.groupingBy(BudgetControlAccount::getDeptId));
		
		return groupMap.get(deptId) ;
	}

}
